package com.ming.stringstudy.feedbacksystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ming.stringstudy.feedbacksystem.anno.PermissionLog;
import com.ming.stringstudy.feedbacksystem.entity.Comment;
import com.ming.stringstudy.feedbacksystem.entity.Reply;
import com.ming.stringstudy.feedbacksystem.entity.UserCommentRelation;
import com.ming.stringstudy.feedbacksystem.mapper.CommentMapper;
import com.ming.stringstudy.feedbacksystem.mapper.ReplyMapper;
import com.ming.stringstudy.feedbacksystem.mapper.UserCommentRelationMapper;
import com.ming.stringstudy.feedbacksystem.service.IReplyService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.ming.stringstudy.feedbacksystem.utils.PermissionConstants.COMMENT_REPLY;
import static com.ming.stringstudy.feedbacksystem.utils.PermissionConstants.REPLY_VIEW;

/**
 * <p>
 * 回复意见/问题表 服务实现类
 * </p>
 *
 * @author aming
 * @since 2024-12-24
 */
@Service
public class ReplyServiceImpl extends ServiceImpl<ReplyMapper, Reply> implements IReplyService {
    private final ReplyMapper replyMapper;
    private final UserCommentRelationMapper userCommentRelationMapper;
    private final CommentMapper commentMapper;
    // 构造器注入
    public ReplyServiceImpl(ReplyMapper replyMapper, UserCommentRelationMapper userCommentRelationMapper, CommentMapper commentMapper) {
        this.replyMapper = replyMapper;
        this.userCommentRelationMapper = userCommentRelationMapper;
        this.commentMapper = commentMapper;
    }
    @PermissionLog(COMMENT_REPLY)
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean insertReplyService(Reply reply) {
        //判断是否重复添加过是否能添加
        // Repeat:重复
        boolean userCommentRelationsRepeat = getUserCommentRelationsRepeat(reply);
        boolean commentRepeat = getCommentReplyRepeat(reply);
        boolean replyRepeat = getReplyRepeat(reply);
        // 判断
        if(replyRepeat){// 是否能回复
            replyMapper.insert(reply);
            if (userCommentRelationsRepeat) { // 是否表中已经这个用户与这个问题的关系了
                userCommentRelationMapper.insert(new UserCommentRelation(reply.getUserId(),reply.getCommentId(),(byte)1));
            }
            if (commentRepeat) { //是否问题表中，是否为未回复
                commentMapper.updateCommentStateById(reply.getCommentId(),(byte)1);
            }
            return true;
        }else{
            return false;
        }
    }
    @PermissionLog(REPLY_VIEW)
    @Override
    public List<Reply> selectReplyList(Integer commentId) {
        LambdaQueryWrapper<Reply> replyWrapper = new LambdaQueryWrapper<>();
        replyWrapper.eq(Reply::getCommentId,commentId);
        replyWrapper.orderByAsc(Reply::getCreateTime);// 按照时间升序
        List<Reply> replies = replyMapper.selectList(replyWrapper);
        return replies;
    }

    /**
     * 防止重复回复
     * 如果在一个行中，这两个字段一样，就返回非空，
     * @param reply
     * @return
     */
    private boolean getUserCommentRelationsRepeat(Reply reply) {
        Long userCommentRelations = userCommentRelationMapper.selectCount(new LambdaQueryWrapper<UserCommentRelation>()
                .eq(UserCommentRelation::getUserId, reply.getUserId())
                .eq(UserCommentRelation::getCommentId, reply.getCommentId())
        );
        // 0 表示没有重复录入，加
        // 1 表示重复录入不加
        return userCommentRelations == 0;
    }

    /**
     * 判断这个问题是否已经未回复
     * @param reply
     * @return
     */
    private boolean getCommentReplyRepeat(Reply reply) {
        // 如果这条问题为state为0表示未回复
        Long comments = commentMapper.selectCount(new LambdaQueryWrapper<Comment>()
                .eq(Comment::getCommentState, 0)
                .eq(Comment::getId, reply.getCommentId())
        );
        // 等于0代码已经修改了，无需重复修改
        // 大于等于0代表，这是第一次回复需要修改
        return comments > 0;
    }

    /**
     * 如果为为回复/回复状态，可以进行回复/追加回复，但是一旦评论就不可回复了
     * @param reply
     * @return
     */
    private boolean getReplyRepeat(Reply reply) {
        Long comments = commentMapper.selectCount(new LambdaQueryWrapper<Comment>()
                .in(Comment::getCommentState,0,1)
                .eq(Comment::getId, reply.getCommentId())
        );
        // 0 代码着已经不能回复了
        // 大于等于0代表着，是可以回复的
        return comments > 0;
    }
}
